/******************** (C) COPYRIGHT 2014 SONiX *******************************
* COMPANY:			SONiX
* DATE:					2014/01
* AUTHOR:				SA1
* IC:						SN32F240
* DESCRIPTION:	
*____________________________________________________________________________
* REVISION	Date				User		Description
*
*____________________________________________________________________________
* THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS TIME TO MARKET.
* SONiX SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR CONSEQUENTIAL 
* DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT OF SUCH SOFTWARE
* AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION CONTAINED HEREIN 
* IN CONNECTION WITH THEIR PRODUCTS.
*****************************************************************************/

/*_____ I N C L U D E S ____________________________________________________*/
#include "stdlib.h"
#include <SN32F280.h>
#include "OLED_Display.h"
#include "LED_Driver.h"
#include "LED_Code.h"
#include "OLED_Code.h"
#include "LED_Display.h"
#include	"..\UsbHid\hid.h"
#include	"..\UsbHid\hidram.h"
#include "..\Driver\PWM.h"
#include "..\Project\FlashRom.h"
#include "..\KB\KB_Flash.h"
#include "..\KB\KB_API.h"
#include "..\KB\KB_BT.h"
#include "..\KB\KB_Scan.h"
#include "..\KB\KB_API_Tab.h"

/*_____ D E C L A R A T I O N S ____________________________________________*/
uint8_t f_OLED_update;
uint8_t rOLED_mode;
uint16_t rOLED_update_cnt_reload;
uint16_t rOLED_update_cnt;
uint16_t rOLED_buf[OLED_NUM];
uint8_t gOLED_buf[OLED_NUM];
uint8_t OLED_DutyIndex[OLED_NUM];

uint8_t ROPWM_Base_Buf[OLED_NUM];
uint8_t GOPWM_Base_Buf[OLED_NUM];
uint8_t BOPWM_Base_Buf[OLED_NUM];
uint8_t rOPWM_DutyBuf[OLED_NUM];

uint8_t rOLED_index;
uint8_t f_OLEDMoveLeft;
uint8_t rODarkenCnt;
uint8_t f_OdarkenIrq;
uint8_t f_enable_Odarken;
uint8_t f_update_Opwmbuf;
uint8_t rOLED_user_mode;
uint8_t rOLED_colour_mode;
uint8_t rOLED_SpeedMode;
uint8_t rOLED_SpeedParam;
uint8_t	rOLED_LightMode;
uint8_t	rOLED_LightParam;
uint16_t rOLED_update_cnt_set;
uint8_t rOLED_colour_mode_max;
uint8_t f_OLEDStop;
uint8_t rOLED_Colour_index;
uint8_t rOLED_Cnt;
uint8_t rOLED_ShiftBuf;

void OLED_iPWMBuf_Update(void);
void OLED_const_design(void);
void OLED_breath_design(void);
void OLED_spectrum_design(void);
void OLED_roll_design(void);
void OLED_spring_design(void);
void OLED_rotate_design(void);
void OLED_snake_design(void);
void OLED_M_roll_design(void);
void OLED_M_spring_design(void);
void OLED_M_rotate_design(void);
void OLED_M_breath_design(void);
void OLED_off_design(void);
void OLED_test_design(void);
void OLED_All_darken(void);
void OLED_Speed_Update(void);
void OLED_All_TurnOff(void);
#define		ODARKEN_CNT			4
/*_____ M A C R O S ________________________________________________________*/

/*_____ F U N C T I O N S __________________________________________________*/
/*****************************************************************************
* Function		: OLED_Init
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_Init(void)
{
	OLED_All_TurnOff();
	f_OLEDMoveLeft = 0;
	rOLED_user_mode = *(volatile uint8_t *)(ROM_USER_ADDR+6);
	rOLED_colour_mode = *(volatile uint8_t *)(ROM_USER_ADDR+7);
//	rOLED_LightMode = *(volatile uint8_t *)(ROM_R9ESET_ADDR+8);
//	rOLED_SpeedMode = *(volatile uint8_t *)(ROM_RESET_ADDR+9);
	rOLED_LightMode = *(volatile uint8_t *)(ROM_USER_ADDR+8);
	rOLED_SpeedMode = *(volatile uint8_t *)(ROM_USER_ADDR+9);
	rOLED_colour_mode_max = OLED_SwitchMode_TAB[rOLED_user_mode][1];
	OLED_Light_Update();
	OLED_Speed_Update();
	OLED_user_mode_switch();
	f_OLEDMoveLeft = 0;
	f_OLEDStop = 0;
//	if(rOLED_colour_mode == API_COLOUR_SET)
//	{
//		API_User_Set.rDuty_OLED = *(volatile uint8_t *)(ROM_USER_OLED_API_ADDR+0);
//		API_User_Set.gDuty_OLED = *(volatile uint8_t *)(ROM_USER_OLED_API_ADDR+1);
//		API_User_Set.bDuty_OLED = *(volatile uint8_t *)(ROM_USER_OLED_API_ADDR+2);
//		API_User_Set.colour_OLED = *(volatile uint8_t *)(ROM_USER_OLED_API_ADDR+3);
//		API_User_Set.light_OLED = *(volatile uint8_t *)(ROM_USER_OLED_API_ADDR+4);
//		API_User_Set.speed_OLED = *(volatile uint8_t *)(ROM_USER_OLED_API_ADDR+5);
//		API_User_Set.dir_OLED = *(volatile uint8_t *)(ROM_USER_OLED_API_ADDR+6);	
//		
//		f_OLEDMoveLeft = 0;
//		if(API_User_Set.dir_OLED == 1)
//			f_OLEDMoveLeft = 1;
//		else if(API_User_Set.dir_OLED == 2)
//			f_OLEDMoveLeft = 1;
//				
//		rOLED_LightMode = API_User_Set.light_OLED;
//		OLED_Light_Update();	
//		OLED_user_mode_switch();
//		rOLED_SpeedMode = API_User_Set.speed_OLED;
//		OLED_Speed_Update();	
//	}
}
/*****************************************************************************
* Function		: OLED_All_darken
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_All_darken(void)
{
	uint8_t i;
	if(f_enable_Odarken)
	{
		for(i=0;i<OLED_NUM;i++)
		{
			if(rOPWM_DutyBuf[i]>0)
			{
				rOPWM_DutyBuf[i]--;
			}
		}
	}	
}

/*****************************************************************************
* Function		: OLED_Display
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_Display(void)
{
//	if((f_USB_NoSignal)&&(rSys_mode == SYS_USB_MODE))
//		return;
//	if(f_OLEDStop)
//		return;
	if(f_OLED_update)
	{
		f_OLED_update = 0;
		switch(rOLED_user_mode)
		{
			case 0:			  OLED_M_roll_design();		break;
			case 1:				OLED_const_design();		break;	
			case 2:				OLED_const_design();		break;	
			case 3:				OLED_const_design();		break;	
			case 4:				OLED_const_design();		break;	
			case 5:				OLED_const_design();		break;	
			case 6:				OLED_const_design();		break;	
			case 7:				OLED_const_design();		break;			
			case 8:		OLED_spectrum_design();	break;			
			case 9:					//OLED_off_design();	
			{

				uint8_t i;
				for(i=0;i<OLED_NUM;i++)
				{
					rOPWM_DutyBuf[i] = 0x00;
					
					ROPWM_Base_Buf[i] = 0;
					GOPWM_Base_Buf[i] = 0;
					BOPWM_Base_Buf[i] = 0;
				}
			}				
			
			break;
			default:		break;
		}
		f_update_Opwmbuf = 1;
	}
	if(f_update_Opwmbuf)
	{
		OLED_iPWMBuf_Update();	
	}
}

/*****************************************************************************
* Function		: User_mode_switch
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_iPWMBuf_Update(void)
{
	uint8_t i,j;
	
	for(j =0;j<OLED_LINE_TAB_LEN;j++)
	{
		i = OLED_LINE_TAB[j];	
		iRPWM_Buf[i] = ((ROPWM_Base_Buf[j]*rOPWM_DutyBuf[j])>>8);
		iGPWM_Buf[i] = ((GOPWM_Base_Buf[j]*rOPWM_DutyBuf[j])>>8);
		iBPWM_Buf[i] = ((BOPWM_Base_Buf[j]*rOPWM_DutyBuf[j])>>8);	
	}	
	
//	for(j =0;j<OLED_LINE_TAB2_LEN;j++)
//	{
//		i = OLED_LINE_TAB2[j];
//		iRPWM_Buf[i] = ((ROPWM_Base_Buf[j]*rOPWM_DutyBuf[j])>>8);
//		iGPWM_Buf[i] = ((GOPWM_Base_Buf[j]*rOPWM_DutyBuf[j])>>8);
//		iBPWM_Buf[i] = ((BOPWM_Base_Buf[j]*rOPWM_DutyBuf[j])>>8);	
//	}	
}

/*****************************************************************************
* Function		: User_mode_switch
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_user_mode_switch(void)
{
	if(rOLED_user_mode>OLED_USER_NUM)
	{
		rOLED_user_mode = *(volatile uint8_t *)(ROM_USER_ADDR+6);	
	}
	
	switch(rOLED_user_mode)
	{
		case 0:       OLED_M_roll_init(); break;
		case 1:				OLED_const_init();		break;
		case 2:				OLED_const_init();		break;
		case 3:				OLED_const_init();		break;
		case 4:				OLED_const_init();		break;
		case 5:				OLED_const_init();		break;
		case 6:				OLED_const_init();		break;
		case 7:				OLED_const_init();		break;
		case OLED_USER_SPECTRUM:		OLED_spectrum_init();	break;
		case 9:					OLED_off_init();   break;
		default:	
			break;
	}
}

/*****************************************************************************
* Function		: OLED_colour_mode_switch
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_colour_mode_switch(void)
{
	rOLED_colour_mode = OLED_SwitchMode_TAB[rOLED_user_mode][0];
	rOLED_colour_mode_max = OLED_SwitchMode_TAB[rOLED_user_mode][1];
}
/*****************************************************************************
* Function		: OLED_const_init
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_const_init(void)
{
	uint8_t i;
	rOLED_mode = rOLED_user_mode;
	rOLED_update_cnt_set = OLED_CONST_TIME;
	OLED_Speed_Update();
	rOLED_index = 0;
	f_enable_Odarken = 0;
//	if(rOLED_colour_mode == API_COLOUR_SET)
//	{
//		for(i=0;i<OLED_NUM;i++)
//		{
//			ROPWM_Base_Buf[i]= API_User_Set.rDuty_OLED;
//			BOPWM_Base_Buf[i]= API_User_Set.gDuty_OLED;
//			GOPWM_Base_Buf[i]= API_User_Set.bDuty_OLED;
//			rOPWM_DutyBuf[i] = PWM_MAX;
//		}	
//	}
//	else
	{
		for(i=0;i<OLED_NUM;i++)
		{
			ROPWM_Base_Buf[i] = LED_TestBaseColour_TAB[rOLED_user_mode][0];
			GOPWM_Base_Buf[i] = LED_TestBaseColour_TAB[rOLED_user_mode][1];
			BOPWM_Base_Buf[i] = LED_TestBaseColour_TAB[rOLED_user_mode][2];
			rOPWM_DutyBuf[i] = 0xC8;
		}		
	}
	
//	if(rOLED_colour_mode == OLED_MulColour_MODE)
//		OLED_spectrum_init();
}

/*****************************************************************************
* Function		: OLED_const_design
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_const_design(void)
{
	uint8_t i;
//	if(rOLED_colour_mode == API_COLOUR_SET)
//	{
//		for(i=0;i<OLED_NUM;i++)
//		{
//			ROPWM_Base_Buf[i]= API_User_Set.rDuty_OLED;
//			BOPWM_Base_Buf[i]= API_User_Set.gDuty_OLED;
//			GOPWM_Base_Buf[i]= API_User_Set.bDuty_OLED;
//			rOPWM_DutyBuf[i] = PWM_MAX;
//		}	
//	}
//	else
	{
		for(i=0;i<OLED_NUM;i++)
		{
			ROPWM_Base_Buf[i] = LED_TestBaseColour_TAB[rOLED_user_mode][0];
			GOPWM_Base_Buf[i] = LED_TestBaseColour_TAB[rOLED_user_mode][1];
			BOPWM_Base_Buf[i] = LED_TestBaseColour_TAB[rOLED_user_mode][2];
			rOPWM_DutyBuf[i] = 0xC8;
		}
	}
}
	
/*****************************************************************************
* Function		: OLED_breath_init
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_M_breath_init(void)
{
	uint8_t i;
	if(rOLED_mode != OLED_M_BREATH_MODE)
		rOLED_index = 0;
	rOLED_mode = OLED_M_BREATH_MODE;
	rOLED_update_cnt_set = OLED_BREATH_TIME;
	OLED_Speed_Update();
	f_enable_Odarken = 0;
	
//	if(rOLED_colour_mode == API_COLOUR_SET)
//	{
//		for(i=0;i<OLED_NUM;i++)
//		{
//			ROPWM_Base_Buf[i]= API_User_Set.rDuty_OLED;
//			BOPWM_Base_Buf[i]= API_User_Set.gDuty_OLED;
//			GOPWM_Base_Buf[i]= API_User_Set.bDuty_OLED;
//			rOPWM_DutyBuf[i] = 0x00;
//		}	
//	}
//	else
	{
		for(i=0;i<OLED_NUM;i++)
		{
			rOPWM_DutyBuf[i] = 0x00;
			
			ROPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[rOLED_colour_mode][0];
			GOPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[rOLED_colour_mode][1];
			BOPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[rOLED_colour_mode][2];
		}		
	}
}

/*****************************************************************************
* Function		: OLED_breath_design
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_M_breath_design(void)
{
	uint8_t i;
	rOLED_index ++;
	if(rOLED_index>=LED_BREATH_TAB_LEN)
	{
		rOLED_index = 0;	
		rOLED_colour_mode++;
		if(rOLED_colour_mode>=OLED_MulColour_MODE)		
			rOLED_colour_mode = 0;
	}

//	if(rOLED_colour_mode == API_COLOUR_SET)
//	{
//		for(i=0;i<OLED_NUM;i++)
//		{
//			ROPWM_Base_Buf[i]= API_User_Set.rDuty_OLED;
//			BOPWM_Base_Buf[i]= API_User_Set.gDuty_OLED;
//			GOPWM_Base_Buf[i]= API_User_Set.bDuty_OLED;
//			rOPWM_DutyBuf[i] = rOLED_index;
//		}	
//	}
//	else
	{
		for(i=0;i<OLED_NUM;i++)
		{
			ROPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[rOLED_colour_mode][0];
			GOPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[rOLED_colour_mode][1];
			BOPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[rOLED_colour_mode][2];
			rOPWM_DutyBuf[i] = LED_BREATH_TAB[rOLED_index];;
		}	
	}
}

/*****************************************************************************
* Function		: OLED_breath_init
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_breath_init(void)
{
	uint8_t i;
	if(rOLED_mode != OLED_BREATH_MODE)
		rOLED_index = 0;
	rOLED_mode = OLED_BREATH_MODE;
	rOLED_update_cnt_set = OLED_BREATH_TIME;
	OLED_Speed_Update();
	f_enable_Odarken = 0;
	
//	if(rOLED_colour_mode == API_COLOUR_SET)
//	{
//		for(i=0;i<OLED_NUM;i++)
//		{
//			ROPWM_Base_Buf[i]= API_User_Set.rDuty_OLED;
//			BOPWM_Base_Buf[i]= API_User_Set.gDuty_OLED;
//			GOPWM_Base_Buf[i]= API_User_Set.bDuty_OLED;
//			rOPWM_DutyBuf[i] = 0x00;
//		}	
//	}
	if(rOLED_colour_mode < OLED_MulColour_MODE)
	{
		for(i=0;i<OLED_NUM;i++)
		{
			rOPWM_DutyBuf[i] = 0x00;
			ROPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[rOLED_colour_mode][0];
			GOPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[rOLED_colour_mode][1];
			BOPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[rOLED_colour_mode][2];
		}		
	}
	else
	{
		rOLED_Colour_index = 0;
		for(i=0;i<OLED_NUM;i++)
		{
			rOPWM_DutyBuf[i] = 0x00;
			ROPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[rOLED_Colour_index][0];
			GOPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[rOLED_Colour_index][1];
			BOPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[rOLED_Colour_index][2];		
		}
	}
}

/*****************************************************************************
* Function		: OLED_breath_design
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_breath_design(void)
{
	uint8_t i;
	rOLED_index ++;
	if(rOLED_index>=LED_BREATH_TAB_LEN)
	{
		rOLED_index = 0;		
	
		if(rOLED_colour_mode < OLED_MulColour_MODE)
		{
			for(i=0;i<OLED_NUM;i++)
			{
				ROPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[rOLED_colour_mode][0];
				GOPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[rOLED_colour_mode][1];
				BOPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[rOLED_colour_mode][2];
			}		
		}
		else
		{
			rOLED_Colour_index ++;
			if(rOLED_Colour_index>=OLED_MulColour_MODE)
				rOLED_Colour_index = 0;
		
			for(i=0;i<OLED_NUM;i++)
			{
				ROPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[rOLED_Colour_index][0];
				GOPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[rOLED_Colour_index][1];
				BOPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[rOLED_Colour_index][2];		
			}
		}
	}

//	if(rOLED_colour_mode == API_COLOUR_SET)
//	{
//		for(i=0;i<OLED_NUM;i++)
//		{
//			ROPWM_Base_Buf[i]= API_User_Set.rDuty_OLED;
//			BOPWM_Base_Buf[i]= API_User_Set.gDuty_OLED;
//			GOPWM_Base_Buf[i]= API_User_Set.bDuty_OLED;
//			rOPWM_DutyBuf[i] = rOLED_index;
//		}	
//	}
//	else
	for(i=0;i<OLED_NUM;i++)
	{
		rOPWM_DutyBuf[i] = LED_BREATH_TAB[rOLED_index];
	}	
}

/*****************************************************************************
* Function		: OLED_breath_init
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_spectrum_init(void)
{
	uint8_t i;
	rOLED_mode = OLED_SPECTRUM_MODE;
	rOLED_update_cnt_set = OLED_SPECTRUM_TIME;
	OLED_Speed_Update();
	rOLED_index = 0;
	f_enable_Odarken = 0;
	
	for(i=0;i<OLED_NUM;i++)
	{
		ROPWM_Base_Buf[i] = SPECTRUM_COLOUR_TAB[rOLED_index][0];
		GOPWM_Base_Buf[i] = SPECTRUM_COLOUR_TAB[rOLED_index][1];
		BOPWM_Base_Buf[i] = SPECTRUM_COLOUR_TAB[rOLED_index][2];
		
		rOPWM_DutyBuf[i] = PWM_MAX;
	}
}

/*****************************************************************************
* Function		: OLED_breath_design
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_spectrum_design(void)
{
	uint8_t i;
	rOLED_index++;
	if(rOLED_index>=SPECTRUM_COLOUR_TAB_LEN)
		rOLED_index = 0;
	
	for(i=0;i<OLED_NUM;i++)
	{
		ROPWM_Base_Buf[i] = SPECTRUM_COLOUR_TAB[rOLED_index][0];
		GOPWM_Base_Buf[i] = SPECTRUM_COLOUR_TAB[rOLED_index][1];
		BOPWM_Base_Buf[i] = SPECTRUM_COLOUR_TAB[rOLED_index][2];
	}
}

/*****************************************************************************
* Function		: OLED_roll_init
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_roll_init(void)
{
	uint8_t i;
	rOLED_mode = OLED_ROLL_MODE;
	rOLED_update_cnt_set = OLED_ROLL_TIME;
	OLED_Speed_Update();
	
	rOLED_index = 0;
	f_enable_Odarken = 0;
	
	for(i=0;i<OLED_NUM;i++)
	{
		OLED_DutyIndex[i] = OLED_ROLL_INIT_TAB[i];
		ROPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[rOLED_colour_mode][0];
		GOPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[rOLED_colour_mode][1];
		BOPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[rOLED_colour_mode][2];
		rOPWM_DutyBuf[i] = OLED_ROLL_DUTY_TAB[OLED_DutyIndex[i]];
	}
}

/*****************************************************************************
* Function		: OLED_roll_design
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_roll_design(void)
{
	uint8_t i;
	for(i=0;i<OLED_NUM;i++)
	{
		if(f_LEDMoveLeft)
		{
			OLED_DutyIndex[i]++;
			if(OLED_DutyIndex[i]>=OLED_ROLL_DUTY_TAB_LEN)
				OLED_DutyIndex[i] = 0;		
		}
		else
		{
			if(OLED_DutyIndex[i] == 0)
			{
				OLED_DutyIndex[i] = (OLED_ROLL_DUTY_TAB_LEN - 1);
			}
			else
				OLED_DutyIndex[i]--;
		}
		
		rOPWM_DutyBuf[i] = OLED_ROLL_DUTY_TAB[OLED_DutyIndex[i]];
	}
}

/*****************************************************************************
* Function		: OLED_roll_init
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_M_roll_init(void)
{
	uint8_t i;
	rOLED_mode = OLED_M_ROLL_MODE;
	rOLED_update_cnt_set = OLED_M_ROLL_TIME;
	OLED_Speed_Update();
	
	rOLED_index = 0;
	f_enable_Odarken = 0;
	f_OLEDMoveLeft = 0;
	
	for(i=0;i<OLED_M_ROLL_INIT_TAB_LEN;i++)
	{
		rOLED_buf[i] = OLED_M_ROLL_INIT_TAB[i];	
		rOPWM_DutyBuf[i] = PWM_MAX;					
	}
}

/*****************************************************************************
* Function		: OLED_roll_design
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_M_roll_design(void)
{
	uint8_t i;
	for(i=0;i<OLED_M_ROLL_INIT_TAB_LEN;i++)
	{
		if(f_OLEDMoveLeft == 1)
		{
			rOLED_buf[i]++;
			if(rOLED_buf[i]>=SPECTRUM_COLOUR_TAB_LEN)
				rOLED_buf[i] = 0;
		}
		else
		{
			if(rOLED_buf[i] == 0)
			{
				rOLED_buf[i] = SPECTRUM_COLOUR_TAB_LEN -1;
			}
			else
				rOLED_buf[i] --;		
		}
				
		ROPWM_Base_Buf[i] = SPECTRUM_COLOUR_TAB[rOLED_buf[i]][0];
		GOPWM_Base_Buf[i] = SPECTRUM_COLOUR_TAB[rOLED_buf[i]][1];
		BOPWM_Base_Buf[i] = SPECTRUM_COLOUR_TAB[rOLED_buf[i]][2];	
	}
}

/*****************************************************************************
* Function		: OLED_spring_init
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_spring_init(void)
{
	uint8_t i;
	rOLED_mode = OLED_SPRING_MODE;
	rOLED_update_cnt_set = OLED_SPRING_TIME;
	OLED_Speed_Update();
	
	rOLED_index = 0;
	f_enable_Odarken = 0;
	
	for(i=0;i<OLED_SPRING_TAB_LEN;i++)
	{
		OLED_DutyIndex[i] = OLED_SPRING_INIT_TAB[i];
		rOPWM_DutyBuf[OLED_SPRING_TAB[i][0]] = OLED_SPRING_INIT_TAB[i];
		rOPWM_DutyBuf[OLED_SPRING_TAB[i][1]] = OLED_SPRING_INIT_TAB[i];
		
		ROPWM_Base_Buf[OLED_SPRING_TAB[i][0]] = LED_ALL_COLOUR_TAB[rOLED_colour_mode][0];
		GOPWM_Base_Buf[OLED_SPRING_TAB[i][0]] = LED_ALL_COLOUR_TAB[rOLED_colour_mode][1];
		BOPWM_Base_Buf[OLED_SPRING_TAB[i][0]] = LED_ALL_COLOUR_TAB[rOLED_colour_mode][2];
		
		ROPWM_Base_Buf[OLED_SPRING_TAB[i][1]] = LED_ALL_COLOUR_TAB[rOLED_colour_mode][0];
		GOPWM_Base_Buf[OLED_SPRING_TAB[i][1]] = LED_ALL_COLOUR_TAB[rOLED_colour_mode][1];
		BOPWM_Base_Buf[OLED_SPRING_TAB[i][1]] = LED_ALL_COLOUR_TAB[rOLED_colour_mode][2];
	}
}

/*****************************************************************************
* Function		: OLED_roll_design
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_spring_design(void)
{
	uint8_t i;
	for(i=0;i<OLED_SPRING_INIT_TAB_LEN;i++)
	{
		if(f_LEDMoveLeft)
		{
			OLED_DutyIndex[i]++;
			if(OLED_DutyIndex[i]>=OLED_ROLL_DUTY_TAB_LEN)
				OLED_DutyIndex[i] = 0;		
		}
		else
		{
			if(OLED_DutyIndex[i] == 0)
			{
				OLED_DutyIndex[i] = (OLED_ROLL_DUTY_TAB_LEN - 1);
			}
			else
				OLED_DutyIndex[i]--;
		}
		rOPWM_DutyBuf[OLED_SPRING_TAB[i][0]] = OLED_ROLL_DUTY_TAB[OLED_DutyIndex[i]];
		rOPWM_DutyBuf[OLED_SPRING_TAB[i][1]] = OLED_ROLL_DUTY_TAB[OLED_DutyIndex[i]];
	}
}
/*****************************************************************************
* Function		: OLED_spring_init
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_M_spring_init(void)
{
	uint8_t i,j,k;
	
	rOLED_mode = OLED_M_SPRING_MODE;
	rOLED_update_cnt_set = OLED_M_SPRING_TIME;
	OLED_Speed_Update();
	
	rOLED_index = 0;
	f_enable_Odarken = 0;
	
	for(i=0;i<OLED_SPRING_TAB_LEN;i++)
	{
		for(j=0;j<2;j++)
		{
			k = OLED_SPRING_TAB[i][j];
			rOLED_buf[k] = OLED_M_SPRING_INIT_TAB[i];		
			
			ROPWM_Base_Buf[k] = SPECTRUM_COLOUR_TAB[rOLED_buf[k]][0];
			GOPWM_Base_Buf[k] = SPECTRUM_COLOUR_TAB[rOLED_buf[k]][1];
			BOPWM_Base_Buf[k] = SPECTRUM_COLOUR_TAB[rOLED_buf[k]][2];				
		}
	}
	for(i=0;i<OLED_NUM;i++)
	{
		rOPWM_DutyBuf[i] = PWM_MAX;
	}
}

/*****************************************************************************
* Function		: OLED_spring_design
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_M_spring_design(void)
{
	uint8_t i,j,k;
	for(i=0;i<OLED_SPRING_TAB_LEN;i++)
	{
		for(j=0;j<2;j++)
		{
			if(f_OLEDMoveLeft == 1)
			{
				rOLED_buf[i]++;
				if(rOLED_buf[i]>=LED_SPECTRUM_TAB_LEN)
					rOLED_buf[i] = 0;
			}
			else
			{
				if(rOLED_buf[i] == 0)
				{
					rOLED_buf[i] = LED_SPECTRUM_TAB_LEN -1;
				}
				else
					rOLED_buf[i] --;		
			}
			
			k = OLED_SPRING_TAB[i][j];			
			ROPWM_Base_Buf[k] = SPECTRUM_COLOUR_TAB[rOLED_buf[i]][0];
			GOPWM_Base_Buf[k] = SPECTRUM_COLOUR_TAB[rOLED_buf[i]][1];
			BOPWM_Base_Buf[k] = SPECTRUM_COLOUR_TAB[rOLED_buf[i]][2];				
		}
	}
}
/*****************************************************************************
* Function		: OLED_roll_init
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_rotate_init(void)
{
	uint8_t i,j;
	rOLED_mode = OLED_ROTATE_MODE;
	rOLED_update_cnt_set = OLED_ROTATE_TIME;
	OLED_Speed_Update();
	
	rOLED_index = 0;
	f_enable_Odarken = 0;
	rOLED_buf[0] = 0;
	
	j = OLED_LINE_TAB[rOLED_buf[0]];
	rOPWM_DutyBuf[j] = LED_HalfGamma64_TAB_LEN;

	j = OLED_LINE_TAB[OLED_NUM - 1 - rOLED_buf[0]];
	rOPWM_DutyBuf[j] = LED_HalfGamma64_TAB_LEN;
	for(i=0;i<OLED_NUM;i++)
	{
		ROPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[rOLED_colour_mode][0];
		GOPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[rOLED_colour_mode][1];
		BOPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[rOLED_colour_mode][2];	
	}
}

/*****************************************************************************
* Function		: OLED_roll_design
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_rotate_design(void)
{
	uint8_t i;

	if(f_LEDMoveLeft)
	{
		rOLED_buf[0]++;
		if(rOLED_buf[0]>=OLED_NUM)
			rOLED_buf[0] = 0;		
	}
	else
	{
		if(rOLED_buf[0]== 0)
		{
			rOLED_buf[0] = (OLED_NUM - 1);
		}
		else
			rOLED_buf[0]--;
	}

	i = OLED_LINE_TAB[rOLED_buf[0]];
	rOPWM_DutyBuf[i] = LED_HalfGamma64_TAB_LEN;

	i = OLED_LINE_TAB[OLED_NUM - 1 - rOLED_buf[0]];
	rOPWM_DutyBuf[i] = LED_HalfGamma64_TAB_LEN;
}
/*****************************************************************************
* Function		: OLED_rotate_init
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_M_rotate_init(void)
{
	uint8_t i,j;
	rOLED_mode = OLED_M_ROTATE_MODE;
	rOLED_update_cnt_set = OLED_M_ROTATE_TIME;
	OLED_Speed_Update();
	
	rOLED_index = 0;
	f_enable_Odarken = 0;
	
	for(i=0;i<OLED_NUM;i++)
	{
		j = OLED_LINE_TAB[i];
		rOLED_buf[j] = OLED_M_ROTATE_INIT_TAB[i];
		if(rOLED_buf[j]>=SPECTRUM_COLOUR_TAB_LEN)
		{
			ROPWM_Base_Buf[j] = 0;		
			GOPWM_Base_Buf[j] = 0;		
			BOPWM_Base_Buf[j] = 0;		
		}		
		else
		{			
			ROPWM_Base_Buf[j] = SPECTRUM_COLOUR_TAB[rOLED_buf[j]][0];
			GOPWM_Base_Buf[j] = SPECTRUM_COLOUR_TAB[rOLED_buf[j]][1];
			BOPWM_Base_Buf[j] = SPECTRUM_COLOUR_TAB[rOLED_buf[j]][2];		
		}
	}
	
	for(i=0;i<OLED_NUM;i++)
	{
		j = OLED_LINE_TAB[OLED_NUM - 1 - i];
		gOLED_buf[j] = OLED_M_ROTATE_INIT_TAB[i];
		if((ROPWM_Base_Buf[j]+GOPWM_Base_Buf[j]+BOPWM_Base_Buf[j])==0)
		{			
			if(gOLED_buf[j]>=SPECTRUM_COLOUR_TAB_LEN)
			{
				ROPWM_Base_Buf[j] = 0;		
				GOPWM_Base_Buf[j] = 0;		
				BOPWM_Base_Buf[j] = 0;		
			}		
			else
			{			
				ROPWM_Base_Buf[j] = SPECTRUM_COLOUR_TAB[gOLED_buf[j]][0];
				GOPWM_Base_Buf[j] = SPECTRUM_COLOUR_TAB[gOLED_buf[j]][1];
				BOPWM_Base_Buf[j] = SPECTRUM_COLOUR_TAB[gOLED_buf[j]][2];		
			}		
		}
	}
	
	for(i=0;i<OLED_NUM;i++)
	{
		rOPWM_DutyBuf[i] = PWM_MAX;
	}
}

/*****************************************************************************
* Function		: OLED_rotate_design
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_M_rotate_design(void)
{
	uint8_t i,j;
	for(i=0;i<OLED_NUM;i++)
	{
		j = OLED_LINE_TAB[i];
		if(f_OLEDMoveLeft)
		{
			rOLED_buf[j]++;
			if(rOLED_buf[j]>=SPECTRUM_COLOUR_ROTATE_LEN)
				rOLED_buf[j] = 0;
		}
		else
		{
			if(rOLED_buf[j] == 0)
			{
				rOLED_buf[j] = SPECTRUM_COLOUR_ROTATE_LEN -1;
			}
			else
				rOLED_buf[j] --;
		}
		if(rOLED_buf[j]>=SPECTRUM_COLOUR_TAB_LEN)
		{
			ROPWM_Base_Buf[j] = 0;		
			GOPWM_Base_Buf[j] = 0;		
			BOPWM_Base_Buf[j] = 0;				
		}
		else
		{
			ROPWM_Base_Buf[j] = SPECTRUM_COLOUR_TAB[rOLED_buf[j]][0];
			GOPWM_Base_Buf[j] = SPECTRUM_COLOUR_TAB[rOLED_buf[j]][1];
			BOPWM_Base_Buf[j] = SPECTRUM_COLOUR_TAB[rOLED_buf[j]][2];		
		}
	}
	
	for(i=0;i<OLED_NUM;i++)
	{
		j = OLED_LINE_TAB[OLED_NUM - 1 - i];
		if(f_OLEDMoveLeft)
		{
			gOLED_buf[j]++;
			if(gOLED_buf[j]>=SPECTRUM_COLOUR_ROTATE_LEN)
				gOLED_buf[j] = 0;
		}
		else
		{
			if(gOLED_buf[j] == 0)
			{
				gOLED_buf[j] = SPECTRUM_COLOUR_ROTATE_LEN -1;
			}
			else
				gOLED_buf[j] --;
		}
		
		if((ROPWM_Base_Buf[j]+GOPWM_Base_Buf[j]+BOPWM_Base_Buf[j])==0)
		{
			if(gOLED_buf[j]>=SPECTRUM_COLOUR_TAB_LEN)
			{
				ROPWM_Base_Buf[j] = 0;		
				GOPWM_Base_Buf[j] = 0;		
				BOPWM_Base_Buf[j] = 0;				
			}
			else
			{
				ROPWM_Base_Buf[j] = SPECTRUM_COLOUR_TAB[gOLED_buf[j]][0];
				GOPWM_Base_Buf[j] = SPECTRUM_COLOUR_TAB[gOLED_buf[j]][1];
				BOPWM_Base_Buf[j] = SPECTRUM_COLOUR_TAB[gOLED_buf[j]][2];		
			}		
		}
	}
}

/*****************************************************************************
* Function		: OLED_rotate_init
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_snake_init(void)
{
	uint8_t i;
	rOLED_mode = OLED_SNAKE_MODE;
	rOLED_update_cnt_set = OLED_SNAKE_TIME;
	OLED_Speed_Update();
	
	f_OLEDMoveLeft = 0;
	rOLED_index = 0;
	f_enable_Odarken = 0;
	rOLED_ShiftBuf = 0x03;	
	
	rOLED_index = 0;
	f_enable_Odarken = 0;
	f_OLEDMoveLeft = 0;
	
	if(rOLED_colour_mode < OLED_MulColour_MODE)
	{
		for(i=0;i<OLED_NUM;i++)
		{
			ROPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[rOLED_colour_mode][0];
			GOPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[rOLED_colour_mode][1];
			BOPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[rOLED_colour_mode][2];	
		}	
	}
	else
	{
		for(i=0;i<OLED_M_ROLL_INIT_TAB_LEN;i++)
			rOLED_buf[i] = OLED_M_ROLL_INIT_TAB[i];			
	}
}

/*****************************************************************************
* Function		: OLED_rotate_design
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_snake_design(void)
{
	uint8_t i,j;
	if(rOLED_colour_mode < OLED_MulColour_MODE)
	{
		for(i=0;i<OLED_NUM;i++)
		{
			ROPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[rOLED_colour_mode][0];
			GOPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[rOLED_colour_mode][1];
			BOPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[rOLED_colour_mode][2];	
		}		
	}
	else
	{
		for(i=0;i<OLED_M_ROLL_INIT_TAB_LEN;i++)
		{
			if(rOLED_buf[i] == 0)
			{
				rOLED_buf[i] = LED_SPECTRUM_TAB_LEN -1;
			}
			else
				rOLED_buf[i] --;		
					
			ROPWM_Base_Buf[i] = SPECTRUM_COLOUR_TAB[rOLED_buf[i]][0];
			GOPWM_Base_Buf[i] = SPECTRUM_COLOUR_TAB[rOLED_buf[i]][1];
			BOPWM_Base_Buf[i] = SPECTRUM_COLOUR_TAB[rOLED_buf[i]][2];	
		}	
	}
	
	rOLED_Cnt ++;
	if(rOLED_Cnt>=8)
	{
		rOLED_Cnt = 0;
		if(f_OLEDMoveLeft == 0)	
		{
			if(rOLED_ShiftBuf == 0x01)
				rOLED_ShiftBuf = 0x03;
			else
			{
				rOLED_ShiftBuf <<= 1;
				if(rOLED_ShiftBuf == 0x60)
					f_OLEDMoveLeft = 1;			
			}
		}
		else
		{
			if(rOLED_ShiftBuf == 0x60)
				rOLED_ShiftBuf = 0x30;
			else
			{
				rOLED_ShiftBuf >>= 1;
				if(rOLED_ShiftBuf == 0x01)
					f_OLEDMoveLeft = 0;					
			}
		}
		j = rOLED_ShiftBuf;
		for(i=0;i<6;i++)
		{
			if(j&0x01)
				rOPWM_DutyBuf[i] = PWM_MAX;
			else
				rOPWM_DutyBuf[i] = 0;
			j >>= 1;
		}
	}
}

/*****************************************************************************
* Function		: OLED_off_init
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_off_init(void)
{
	uint8_t i;
	rOLED_mode = OLED_OFF_MODE;
	rOLED_update_cnt_set = OLED_OFF_TIME;
	OLED_Speed_Update();
	
	rOLED_index = 0;
	f_enable_Odarken = 0;
	for(i=0;i<OLED_NUM;i++)
	{
		rOPWM_DutyBuf[i] = 0x00;
	}
}

/*****************************************************************************
* Function		: OLED_off_design
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_off_design(void)
{
	OLED_All_TurnOff();
}

/*****************************************************************************
* Function		: LED_reset_init
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_test_init(void)
{
	uint8_t i;
	rOLED_update_cnt = LED_TEST_TIME;
	rOLED_update_cnt_reload = LED_TEST_TIME;	
	rOLED_LightParam = 32;
	rOLED_mode = OLED_TEST_MODE;
	rOLED_index = 0;
	f_enable_Odarken = 0;
	for(i=0;i<OLED_NUM;i++)
	{
		rOPWM_DutyBuf[i] = 64;
		ROPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[0][0];
		GOPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[0][1];
		BOPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[0][2];	
	}
	f_OLED_update = 1;
}

/*****************************************************************************
* Function		: LED_off_design
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_test_design(void)
{
	uint8_t i;
	if(rLED_lineNO == 0)
	{
		for(i=0;i<OLED_NUM;i++)
		{
			ROPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[0][0];
			GOPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[0][1];
			BOPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[0][2];			
		}
	}
	else if(rLED_lineNO == 1)
	{
		for(i=0;i<OLED_NUM;i++)
		{
			ROPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[3][0];
			GOPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[3][1];
			BOPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[3][2];			
		}
	}
	else if(rLED_lineNO == 2)
	{
		for(i=0;i<OLED_NUM;i++)
		{
			ROPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[5][0];
			GOPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[5][1];
			BOPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[5][2];			
		}
	}
	else if(rLED_lineNO == 3)
	{
		for(i=0;i<OLED_NUM;i++)
		{
			ROPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[7][0];
			GOPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[7][1];
			BOPWM_Base_Buf[i] = LED_ALL_COLOUR_TAB[7][2];			
		}
	}
}

/*****************************************************************************
* Function		: OLED_All_TurnOff
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_All_TurnOff(void)
{
	uint8_t i;
	for(i=0;i<OLED_NUM;i++)
		rOPWM_DutyBuf[i] = 0x00;
}
/*****************************************************************************
* Function		: OLED_Light_Update
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_Light_Update(void)
{
	if(rOLED_colour_mode != API_COLOUR_SET)
		rOLED_LightParam = OLED_LIGHT_TAB[rOLED_LightMode];
	else
		rOLED_LightParam = OLED_API_LIGHT_TAB[rOLED_LightMode];
}

/*****************************************************************************
* Function		: LED_Speed_Update
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_Speed_Update(void)
{
	if(rOLED_colour_mode != API_COLOUR_SET)
		rOLED_SpeedParam = OLED_SPEED_TAB[rOLED_SpeedMode];	
	else
		rOLED_SpeedParam = OLED_API_SPEED_TAB[rOLED_SpeedMode];
	rOLED_update_cnt = rOLED_update_cnt_set*rOLED_SpeedParam/(16*25);
	rOLED_update_cnt_reload = rOLED_update_cnt;	
}

/*****************************************************************************
* Function		: LED_Update_Chat
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_Update_Chat(void)
{
	if(--rOLED_update_cnt == 0)
	{
		rOLED_update_cnt = rOLED_update_cnt_reload;
		f_OLED_update = 1;
	}
}

/*****************************************************************************
* Function		: OLED_Darken_chat
* Description	: 
* Input			: None
* Output		: None
* Return		: None
* Note			: None
*****************************************************************************/
void OLED_Darken_chat(void)
{
	rODarkenCnt++;
	if(rODarkenCnt>ODARKEN_CNT)
	{
		rODarkenCnt = 0;
		f_OdarkenIrq = 1;
	}
}
